package nl.scalasim.ui

import java.util.{Timer, TimerTask}
import scala.actors.Actor
import java.io.File
import nl.scalasim.util.ReplayableGameState
import scala.swing._
import nl.scalasim.{Amount, SaveGameState, Controller}

/**
 * All relevant game actions
 *
 * @author Yigal Duppen
 * @since Nov 7, 2010
 */
class Actions(level: Level, map: MapView) {

  private val SLOW_SPEED = 300
  private val NORMAL_SPEED = 100
  private val FAST_SPEED = 50

  private val timer = new Timer("Game-loop")
  private var running = false
  private var speed = NORMAL_SPEED

  val saveAction = Action("Save game...") {
    val oldRunning = running
    running = false

    val chooser = new FileChooser {title = "Choose your save game"}
    chooser.showSaveDialog(map) match {
      case FileChooser.Result.Approve => {
        val f: File = chooser.selectedFile
        val result = level.historian !? SaveGameState(f)
        println(result)
      }
    }
    running = oldRunning
  }

  val loadAction = Action("Load game...") {
    running = false

    val chooser = new FileChooser {title = "Choose your save game"}
    chooser.showOpenDialog(map) match {
      case FileChooser.Result.Approve => {
        val f: File = chooser.selectedFile
        val state: ReplayableGameState = ReplayableGameState.load(f).right.get

        val progress = new ProgressBar {
          min = 0
          peer.setStringPainted(true)
          indeterminate = true

          def update(progress: Amount) {
            Swing.onEDT {
              indeterminate = false
              max = progress.max
              value = progress.value
            }
          }

        }
        val dialog = new Dialog {
          title = "Loading game..."
          contents = progress
        }
        dialog.open

        Actor.actor {
          level.controller = new Controller(level.setting)
          state.replay(level.controller, progress.update)
          map.updateMap()

          dialog.close
          dialog.dispose
        }
      }
    }
  }

  val pauseAction = Action("Pause") {
    running = false
  }

  val slowAction = Action("Slow speed") {
    speed = SLOW_SPEED
  }

  val normalAction = Action("Normal speed") {
    speed = NORMAL_SPEED
  }

  val fastAction = Action("Fast speed") {
    speed = FAST_SPEED
  }
  
  val stepAction = Action("Step") {
    Actor.actor {
      level.controller.tick()
      map.updateMap()
    }
  }

  val runAction = Action("Run") {
    running = true
  }

  private class RunningTask extends TimerTask {
    def run = {
      timer.schedule(new RunningTask(), speed)
      if (running) {
        stepAction()
      }
    }
  }

  timer.schedule(new RunningTask(), 0)

}